package jmine.tec.web.pages.app;

import java.io.IOException;

import jmine.tec.environment.db.DBEnvironment;
import jmine.tec.environment.db.DBEnvironmentHolder;
import jmine.tec.environment.db.DBLoadedServerUtils;
import jmine.tec.services.environment.RefDBEnvironment;

import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;
import org.springframework.transaction.TransactionStatus;

import bancosys.tec.utils.db.descriptor.FlatReferenceDatabaseBuilder.ReferenceDatabaseDescriptionType;
import bancosys.tec.utils.loader.ResourceLoader;
import bancosys.tec.utils.log.LogManager;

public class MockApplicationStarter {

    private static final int START_WAIT_MILLIS = 5000;

    private static final int CONNECTOR_PORT = 8888;

    private static final int MAX_IDLE_TIME = 1000 * 60 * 60;

    private String war = "src/test/resources";

    private int port = CONNECTOR_PORT;

    private String contextPath = "/";

    /**
     * Prepara o ambiente de testes
     * 
     * @param spring spring
     * @param refdb refdb
     * @param refdbType refdbType
     */
    public void prepareEnvironment(String spring, String refdb, ReferenceDatabaseDescriptionType refdbType) {
        try {
            new LogManager(new ResourceLoader(), "jmine-tec-test-log.properties", true);
        } catch (IOException e) {
            // OK, no log, then
        }
        DBEnvironmentHolder environmentHolder = DBEnvironmentHolder.getInstance();
        DBEnvironment environment = new RefDBEnvironment(environmentHolder.instantiate(spring, refdb));
        environmentHolder.setEnvironment(environment);
        environment.setRefdbType(refdbType);
        environment.restart();
    }

    /**
     * Executa o inicializador de dados
     * 
     * @param initializer initializer
     */
    public void initializeData(Runnable initializer) {
        DBLoadedServerUtils helper = DBEnvironmentHolder.getInstance().getEnvironment().getHelper();
        TransactionStatus status = helper.getTransactionStatus();
        boolean commit = false;
        try {
            initializer.run();
            commit = true;
        } finally {
            if (commit) {
                helper.commit(status);
            } else {
                helper.rollback(status);
            }
        }

    }

    /**
     * Inicia o servidor jetty.
     * 
     * @throws Exception
     */
    public void startJetty() {
        Server server = new Server();
        SocketConnector connector = new SocketConnector();
        connector.setMaxIdleTime(MAX_IDLE_TIME);
        connector.setSoLingerTime(-1);
        connector.setPort(this.port);
        server.setConnectors(new Connector[]{ connector });

        WebAppContext bb = new WebAppContext();
        bb.setServer(server);
        bb.setContextPath(this.contextPath);
        bb.setWar(this.war);

        server.addHandler(bb);

        System.out.println(">>> STARTING EMBEDDED JETTY SERVER, PRESS ANY KEY TO STOP");
        try {
            server.start();
            while (System.in.available() == 0) {
                Thread.sleep(START_WAIT_MILLIS);
            }
            server.stop();
            server.join();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @param war the war to set
     */
    public void setWar(String war) {
        this.war = war;
    }

    /**
     * @param port the port to set
     */
    public void setPort(int port) {
        this.port = port;
    }

    /**
     * @param contextPath the contextPath to set
     */
    public void setContextPath(String contextPath) {
        this.contextPath = contextPath;
    }
}
